package com.atguigu.atcrowdfunding.controller;

import com.atguigu.atcrowdfunding.bean.AJAXResult;
import com.atguigu.atcrowdfunding.bean.Permission;
import com.atguigu.atcrowdfunding.service.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;
import java.util.stream.Collectors;


/**
 * lcd  2020/4/1
 * Description:
 */
@Controller
@RequestMapping("permission")
public class PermissionController {
    @Autowired
    private PermissionService permissionService;

    @RequestMapping("/index")
    public String index() {
        return "permission/index";
    }
    @RequestMapping("/add")
    public String add() {
        return "permission/add";
    }

    @RequestMapping("/edit")
    public String edit(Integer id, Model model) {
        Permission permission=permissionService.findById(id);
        model.addAttribute("permission", permission);
        return "permission/edit";
    }
    /**
     * 动态的获取数据库数据,给permission里面的checked赋值
     **/
    @ResponseBody
    @RequestMapping("/loadCurrentData")
    public Object loadCurrentData(Integer roleid) {
        List<Permission> list = new ArrayList<>();
        List<Permission> permissionList = permissionService.findAll();
        /*
         * 动态给check赋值,多增加这一块
         **/
        List<Integer> currentPermissionIds=permissionService.findPermissionsByRoleId(roleid);//这个角色所拥有的许可权限的id
        for (Permission permission : permissionList) {
            if (currentPermissionIds.contains(permission.getId())) {
                permission.setChecked(true);
            }
        }

        //还是之前的利用索引的构建树
        Map<Integer, Permission> map=new HashMap<>();
        for (Permission permission : permissionList) {
            map.put(permission.getId(), permission);
        }
        for (Permission permission : permissionList) {
            if (permission.getPid() == 0) {
                list.add(permission);
            }else{
                //找爸爸
                Permission parent = map.get(permission.getPid());
                //到这里就说明每个节点都有父亲,就不用判断了
                parent.getChildren().add(permission);
            }
        }
        return list;
    }
    /**
     * 把表格List的数据转成树形的数据结构丢给前端,问题是没有根据数据库动态的获得tree,因此废弃不用,作为思路参考
     * 多种方法的思路
     **/
    @ResponseBody
    @RequestMapping("/loadData")
    public Object loadData() {
        List<Permission> list = new ArrayList<>();
        //1假数据
//        fakeData(list);
        //2写死的查询
//        writeDeadMethod(list);
        //3采用递归的办法来查询,第一层的child就是系统配置
//        recursiveMethod(list);
        //4.1采用一次查询,内部组装的办法,挺难的,双层for循环,复杂度O平方,儿子找父亲
//        findFather(list);
        //4.2试试看父亲找儿子,遍历的次数更多,不如4.1的效率
//        findSon(list);
        //5利用map,利用了索引,效率最高!
        useIndexMap(list);
        return list;
    }

    @ResponseBody
    @RequestMapping("/insert")
    public Object insert(Permission permission) {
        AJAXResult ajaxResult = new AJAXResult();
        try {
            permissionService.insert(permission);
            ajaxResult.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ajaxResult;
    }
    @ResponseBody
    @RequestMapping("/update")
    public Object update(Permission permission) {
        AJAXResult ajaxResult = new AJAXResult();
        try {
            permissionService.update(permission);
            ajaxResult.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ajaxResult;
    }
    @ResponseBody
    @RequestMapping("/delete")
    public Object delete(Integer id) {
        AJAXResult ajaxResult = new AJAXResult();
        try {
            permissionService.delete(id);
            ajaxResult.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ajaxResult;
    }

    private void useIndexMap(List<Permission> list) {
        List<Permission> permissionList = permissionService.findAll();
        Map<Integer, Permission> map=new HashMap<>();
        for (Permission permission : permissionList) {
            map.put(permission.getId(), permission);
        }
        for (Permission permission : permissionList) {
            if (permission.getPid() == 0) {
                list.add(permission);
            }else{
                //找爸爸
                Permission parent = map.get(permission.getPid());
                //到这里就说明每个节点都有父亲,就不用判断了
                parent.getChildren().add(permission);
            }
        }
    }

    private void findSon(List<Permission> list) {
        List<Permission> permissionList = permissionService.findAll();
        for (Permission parent : permissionList) {
            if (parent.getPid() == 0) {
                list.add(parent);
            }
            for (Permission child : permissionList) {
                if (parent.getId().equals(child.getPid())) {
                    parent.getChildren().add(child);
                }
            }
        }
    }
    //外层for循环 相当于是子节点;内层for循环 相当于是父节点,由于子节点只有一个父节点,所以找到了就可以跳出break
    //全部循环完,相当于外层for的每个子节点都找到了父节点,建立了关系就可以了,有一个例外,就是有一个节点是父节点,那么找出来,丢到其他的容器
    private void findFather(List<Permission> list) {
        List<Permission> permissionList = permissionService.findAll();
        for (Permission outterP : permissionList) {
            if (outterP.getPid() == 0) {
                list.add(outterP);
            } else {
                for (Permission innerP : permissionList) {
                    if (outterP.getPid().equals(innerP.getId())) {
                        innerP.getChildren().add(outterP);
                        break;
                    }
                }
            }
        }
    }

    private void recursiveMethod(List<Permission> list) {
        Permission root = new Permission();
        root.setId(0);
        findChildPermissions(root);
        list.add(root);
    }

    private void writeDeadMethod(List<Permission> list) {
        //第一级菜单
        List<Permission> roots=permissionService.findPermissionsByPid(0);//技巧,把顶级节点的pid设置成0,而不用默认的null
        //第二级菜单
        for (Permission permission : roots) {
            List<Permission> children = permissionService.findPermissionsByPid(permission.getId());
            permission.setChildren(children);
            //第三极菜单
            for (Permission child : children) {
                List<Permission> childChild = permissionService.findPermissionsByPid(child.getId());
                child.setChildren(childChild);
            }
        }
        list.add(roots.get(0));
    }

    private void fakeData(List<Permission> list) {
        Permission root=new Permission();
        root.setName("顶级");
        Permission child =new Permission();
        child.setName("子节点1");
        root.getChildren().add(child);
        list.add(root);
    }

    /**
     * 3 递归查询许可
     * 方法自己调用自己,
     * 方法一定要存在跳出逻辑,
     * 方法调用时候,参数要有规律
     * 递归算法效率比较低,访问数据库太多次
     **/
    public void findChildPermissions(Permission parent) {
        List<Permission> child = permissionService.findPermissionsByPid(parent.getId());
        parent.setChildren(child);
        for (Permission permission : child) {
            findChildPermissions(permission);
        }
    }

}
